package cn.edu.baiyunu.myapplication.ui.screens.transactions.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import cn.edu.baiyunu.myapplication.data.model.Category
import cn.edu.baiyunu.myapplication.data.model.Transaction
import cn.edu.baiyunu.myapplication.data.repository.CategoryRepository
import cn.edu.baiyunu.myapplication.data.repository.TransactionRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import java.util.Calendar
import javax.inject.Inject

/**
 * 交易列表界面的ViewModel
 */
@HiltViewModel
class TransactionsViewModel @Inject constructor(
    private val transactionRepository: TransactionRepository,
    private val categoryRepository: CategoryRepository
) : ViewModel() {

    // 当前选择的年份和月份
    private val _currentDate = MutableStateFlow(Calendar.getInstance())
    
    // 过滤条件状态
    private val _filterState = MutableStateFlow(TransactionFilter())
    val filterState: StateFlow<TransactionFilter> = _filterState

    // 所有分类
    private val _allCategories = combine(
        categoryRepository.getExpenseCategories(),
        categoryRepository.getIncomeCategories()
    ) { expenseCategories, incomeCategories ->
        expenseCategories + incomeCategories
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5000),
        initialValue = emptyList()
    )
    
    // 公开的分类StateFlow
    val allCategories: StateFlow<List<Category>> = _allCategories

    // 获取交易记录和关联的分类信息
    @OptIn(ExperimentalCoroutinesApi::class)
    private val transactionsWithCategories = _currentDate.flatMapLatest { calendar ->
        val year = calendar.get(Calendar.YEAR)
        val month = calendar.get(Calendar.MONTH) + 1
        
        transactionRepository.getTransactionsByMonth(year, month).map { transactions ->
            transactions.map { transaction ->
                val category = _allCategories.value.find { it.id == transaction.categoryId }
                    ?: Category(
                        name = "未知分类",
                        icon = "help_outline",
                        type = transaction.type,
                        orderIndex = 0
                    )
                TransactionWithCategory(transaction, category)
            }
        }
    }

    // 应用过滤器后的交易记录
    private val filteredTransactions = combine(
        transactionsWithCategories,
        _filterState
    ) { transactionsWithCategories, filter ->
        transactionsWithCategories.filter { (transaction, category) ->
            // 类型过滤
            (filter.type == null || transaction.type == filter.type) &&
            // 分类过滤
            (filter.categoryIds.isEmpty() || filter.categoryIds.contains(category.id)) &&
            // 金额范围过滤
            (filter.minAmount == null || transaction.amount >= filter.minAmount) &&
            (filter.maxAmount == null || transaction.amount <= filter.maxAmount)
        }
    }

    // 按日期分组的交易记录
    val groupedTransactionsState: StateFlow<Map<Long, List<TransactionWithCategory>>> = 
        filteredTransactions.map { transactions ->
            transactions.groupBy { (transaction, _) ->
                // 将时间戳转换为当天开始的时间戳（去除时分秒）
                val calendar = Calendar.getInstance().apply {
                    timeInMillis = transaction.date
                    set(Calendar.HOUR_OF_DAY, 0)
                    set(Calendar.MINUTE, 0)
                    set(Calendar.SECOND, 0)
                    set(Calendar.MILLISECOND, 0)
                }
                calendar.timeInMillis
            }.toSortedMap(compareByDescending { it }) // 按日期降序排序
        }.stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5000),
            initialValue = emptyMap()
        )

    // UI状态
    val uiState: StateFlow<TransactionsUiState> = combine(
        _currentDate,
        groupedTransactionsState
    ) { calendar, groupedTransactions ->
        TransactionsUiState(
            currentYear = calendar.get(Calendar.YEAR),
            currentMonth = calendar.get(Calendar.MONTH) + 1,
            isEmpty = groupedTransactions.isEmpty()
        )
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5000),
        initialValue = TransactionsUiState()
    )

    // 切换到上一个月
    fun navigateToPreviousMonth() {
        _currentDate.update { calendar ->
            Calendar.getInstance().apply {
                timeInMillis = calendar.timeInMillis
                add(Calendar.MONTH, -1)
            }
        }
    }

    // 切换到下一个月
    fun navigateToNextMonth() {
        _currentDate.update { calendar ->
            Calendar.getInstance().apply {
                timeInMillis = calendar.timeInMillis
                add(Calendar.MONTH, 1)
            }
        }
    }

    // 设置过滤条件
    fun setFilter(filter: TransactionFilter) {
        _filterState.value = filter
    }

    // 重置过滤条件
    fun resetFilter() {
        _filterState.value = TransactionFilter()
    }

    // 删除交易
    fun deleteTransaction(transactionId: String) {
        viewModelScope.launch {
            transactionRepository.deleteTransaction(transactionId)
        }
    }
}

/**
 * 交易记录与对应分类信息
 */
data class TransactionWithCategory(
    val transaction: Transaction,
    val category: Category
)

/**
 * 交易记录过滤条件
 */
data class TransactionFilter(
    val type: String? = null, // "expense" 或 "income"，null 表示不过滤
    val categoryIds: Set<String> = emptySet(),
    val minAmount: Double? = null,
    val maxAmount: Double? = null
)

/**
 * 交易列表UI状态
 */
data class TransactionsUiState(
    val currentYear: Int = Calendar.getInstance().get(Calendar.YEAR),
    val currentMonth: Int = Calendar.getInstance().get(Calendar.MONTH) + 1,
    val isEmpty: Boolean = true
) 